package cn.ilovese.collect.serviceimpl.collaboration_task;

import cn.ilovese.collect.controller.socket.WebSocketServer;
import cn.ilovese.collect.datamapper.collaboration_task.CollaborationTaskDependencyMapper;
import cn.ilovese.collect.datamapper.collaboration_task.CollaborationWorkMapper;
import cn.ilovese.collect.datamapper.collaboration_task.SubTaskAscriptionMapper;
import cn.ilovese.collect.datamapper.collaboration_task.WorkCollocationMapper;
import cn.ilovese.collect.datamapper.device.DeviceRequirementMapper;
import cn.ilovese.collect.datamapper.report.ReportMapper;
import cn.ilovese.collect.datamapper.task.TaskMapper;
import cn.ilovese.collect.datamapper.transaction.TransactionMapper;
import cn.ilovese.collect.datamapper.user.UserMapper;
import cn.ilovese.collect.datamapper.work.WorkMapper;
import cn.ilovese.collect.datamapper.workermessage.WorkerMessageMapper;
import cn.ilovese.collect.po.collaboration_task.CollaborationTaskDependency;
import cn.ilovese.collect.po.collaboration_task.CollaborationWork;
import cn.ilovese.collect.po.collaboration_task.SubTaskAscription;
import cn.ilovese.collect.po.collaboration_task.WorkCollocation;
import cn.ilovese.collect.po.device.DeviceRequirement;
import cn.ilovese.collect.po.report.Report;
import cn.ilovese.collect.po.task.Task;
import cn.ilovese.collect.po.transaction.Transaction;
import cn.ilovese.collect.po.user.User;
import cn.ilovese.collect.po.work.Work;
import cn.ilovese.collect.po.workermessage.WorkerMessage;
import cn.ilovese.collect.service.collaboration_task.CollaborationTaskService;
import cn.ilovese.collect.util.Constant;
import cn.ilovese.collect.vo.Device.DeviceRequirementVO;
import cn.ilovese.collect.vo.NullVO;
import cn.ilovese.collect.vo.ResultVO;
import cn.ilovese.collect.vo.collaboration_task.*;
import cn.ilovese.collect.vo.task.TaskVO;
import cn.ilovese.collect.vo.work.WorkVO;
import com.hankcs.hanlp.dependency.nnparser.Dependency;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@CacheConfig(cacheNames = "collaboration_tasks",cacheManager = "cacheManager")
public class CollaborationTaskImpl implements CollaborationTaskService {
    @Resource
    CollaborationTaskDependencyMapper collaborationTaskDependencyMapper;

    @Resource
    CollaborationWorkMapper collaborationWorkMapper;

    @Resource
    SubTaskAscriptionMapper subTaskAscriptionMapper;

    @Resource
    WorkCollocationMapper workCollocationMapper;

    @Resource
    TaskMapper taskMapper;

    @Resource
    UserMapper userMapper;

    @Resource
    DeviceRequirementMapper deviceRequirementMapper;

    @Resource
    ReportMapper reportMapper;

    @Resource
    TransactionMapper transactionMapper;

    @Resource
    WorkMapper workMapper;

    @Resource
    WorkerMessageMapper workerMessageMapper;

    @Override
    public ResultVO<Integer> createCollaborationTask(CollaborationTaskFromVO collaborationTask) {
        int uid = userMapper.selectByUsername(collaborationTask.getUsername()).getId();
        Task recordCollaborationTask = new Task();
        recordCollaborationTask.setEnvironment("Android8");
        recordCollaborationTask.setUserId(uid);
        recordCollaborationTask.setTaskName(collaborationTask.getTaskname());
        recordCollaborationTask.setDescription(collaborationTask.getDescription());
        recordCollaborationTask.setType("collaboration_test");
        recordCollaborationTask.setNeedNumber(collaborationTask.getNeed_num());
        recordCollaborationTask.setTotalNumber(collaborationTask.getNeed_num());
        recordCollaborationTask.setReportPrice(0);
        recordCollaborationTask.setReportNumber(0);
        Date endTime=collaborationTask.getSubTasks().get(0).getDeadline();
        Date startTime=new Date();
        int priceToSubmit=0;
        for(SubTaskVO temp:collaborationTask.getSubTasks()){
            Date deadLine=temp.getDeadline();
            if(deadLine.compareTo(endTime)>0){
                endTime=deadLine;
            }
            priceToSubmit+=temp.getReportPrice()*collaborationTask.getNeed_num();
            Task subTaskTemp = new Task();
            subTaskTemp.setEnvironment("Android8");
            subTaskTemp.setUserId(4);
            subTaskTemp.setTaskName(temp.getTaskname());
            subTaskTemp.setDescription(temp.getDescription());
            subTaskTemp.setType(temp.getType());
            subTaskTemp.setNeedNumber(collaborationTask.getNeed_num());
            subTaskTemp.setTotalNumber(collaborationTask.getNeed_num());
            subTaskTemp.setStartTime(new Date());
            subTaskTemp.setReportPrice(temp.getReportPrice());
            subTaskTemp.setReportNumber(0);
            subTaskTemp.setEndTime(temp.getDeadline());
            taskMapper.insert(subTaskTemp);
            int idTemp=taskMapper.getMaxTaskId();
            temp.setId(idTemp);
            System.out.println(idTemp);
            if(temp.getDeviceRequirement()!=null){
                DeviceRequirementVO newDeviceRequirement=temp.getDeviceRequirement();
                newDeviceRequirement.setTaskId(temp.getId());
                int device_id=deviceRequirementMapper.insert(
                        new DeviceRequirement(
                                newDeviceRequirement
                        )
                );
                if(device_id<1)
                    System.out.println("插入子任务的设备需求失败");
            }
        }
        recordCollaborationTask.setStartTime(startTime);
        recordCollaborationTask.setEndTime(endTime);
        User bossWithBalance=userMapper.selectByPrimaryKey(uid);
        BigDecimal oldBalance = new BigDecimal(Double.toString(bossWithBalance.getBalance()));
        BigDecimal amount = new BigDecimal(Double.toString(priceToSubmit));
        bossWithBalance.setBalance(oldBalance.subtract(amount).doubleValue());
        if(bossWithBalance.getBalance()<0)
            return new ResultVO<>(Constant.REQUEST_FAIL,"发包方余额不足以发布任务");
        int updateRow=userMapper.updateByPrimaryKey(bossWithBalance);
        if (updateRow==1) {
            long timeNow = System.currentTimeMillis();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            Date nowTime=new Date();
            String nowDate = sdf.format(nowTime);
            String transactionNumber = "RT" + nowDate + timeNow;
            Transaction releaseTaskTransaction = new Transaction();
            releaseTaskTransaction.setTransactionNumber(transactionNumber);
            releaseTaskTransaction.setBalance(bossWithBalance.getBalance());
            releaseTaskTransaction.setIn(0);
            releaseTaskTransaction.setOut(priceToSubmit);
            releaseTaskTransaction.setRemark("任务："+collaborationTask.getTaskname());
            releaseTaskTransaction.setTime(nowTime);
            releaseTaskTransaction.setType("任务扣款");
            releaseTaskTransaction.setUserId(bossWithBalance.getId());
            int transId=transactionMapper.insert(releaseTaskTransaction);
            if(transId<=0){
                return new ResultVO<>(Constant.REQUEST_FAIL,"记录单号失败");
            }
        }
        taskMapper.insert(recordCollaborationTask);
        int id=taskMapper.getMaxTaskId();
        recordCollaborationTask.setId(id);
        for(SubTaskVO temp:collaborationTask.getSubTasks()){
            List<Integer> dependencies=temp.getDependencies();
            for(Integer index:dependencies){
                CollaborationTaskDependency collaborationTaskDependencyTemp=new CollaborationTaskDependency();
                collaborationTaskDependencyTemp.setDownstreamId(temp.getId());
                collaborationTaskDependencyTemp.setUpstreamId(collaborationTask.getSubTasks().get(index).getId());
                collaborationTaskDependencyMapper.insert(collaborationTaskDependencyTemp);
            }
            SubTaskAscription subTaskAscriptionTemp=new SubTaskAscription();
            subTaskAscriptionTemp.setSubTaskId(temp.getId());
            subTaskAscriptionTemp.setParentTaskId(id);
            subTaskAscriptionMapper.insert(subTaskAscriptionTemp);
        }
        if(id < 1)
            return new ResultVO<>(Constant.REQUEST_FAIL, "插入失败");
        else{
            return new ResultVO<>(Constant.REQUEST_SUCCESS,"插入成功", recordCollaborationTask.getId());
        }
    }

    @Override
    public ResultVO<CollaborationTaskVO> getCollaborationTask(Integer taskId) {
        Task task = taskMapper.selectByPrimaryKey(taskId);
        if(task == null)
            return new ResultVO<>(Constant.REQUEST_FAIL,"获取详细信息失败");
        String username = userMapper.selectByPrimaryKey(task.getUserId()).getUsername();
        CollaborationTaskVO res=new CollaborationTaskVO();
        res.setId(task.getId());
        res.setDeadline(task.getEndTime());
        res.setStartTime(task.getStartTime());
        res.setUsername(username);
        res.setType(task.getType());
        res.setDescription(task.getDescription());
        res.setNeed_num(task.getNeedNumber());
        res.setTaskname(task.getTaskName());
        List<SubTaskVO> subTaskVOList=new ArrayList<>();
        List<SubTaskAscription> subTaskAscriptions=subTaskAscriptionMapper.selectByParentTaskId(taskId);
        for(SubTaskAscription temp: subTaskAscriptions){
            Task subTask=taskMapper.selectByPrimaryKey(temp.getSubTaskId());
            SubTaskVO subTaskVO=new SubTaskVO();
            subTaskVO.setId(subTask.getId());
            subTaskVO.setUserId(subTask.getUserId());
            subTaskVO.setUsername(username);
            subTaskVO.setType(subTask.getType());
            subTaskVO.setEnvironment(subTask.getEnvironment());
            subTaskVO.setTaskname(subTask.getTaskName());
            subTaskVO.setDeadline(subTask.getEndTime());
            subTaskVO.setDeviceRequirement(new DeviceRequirementVO(deviceRequirementMapper.selectByTask(subTask.getId())));
            subTaskVO.setDescription(subTask.getDescription());
            subTaskVO.setNeed_num(subTask.getNeedNumber());
            subTaskVO.setTotal_num(subTask.getTotalNumber());
            subTaskVO.setStartTime(subTask.getStartTime());
            subTaskVO.setReportPrice(subTask.getReportPrice());
            List<CollaborationTaskDependency> collaborationTaskDependencies=collaborationTaskDependencyMapper.selectByDownstreamId(subTask.getId());
            List<Integer> dependencies=new ArrayList<>();
            for(CollaborationTaskDependency dependency:collaborationTaskDependencies){
                dependencies.add(dependency.getUpstreamId());
            }
            subTaskVO.setDependencies(dependencies);
            subTaskVOList.add(subTaskVO);
        }
        res.setSubTasks(subTaskVOList);
        return new ResultVO<>(Constant.REQUEST_SUCCESS,"获取详细信息成功", res);
    }

    @Override
    public ResultVO<List<List<ReportSummaryVO>>> getCollaborationTaskReportGroups(Integer taskId) {
        List<List<ReportSummaryVO>> res=new ArrayList<>();
        /*List<SubTaskAscription> subTaskAscriptions=subTaskAscriptionMapper.selectByParentTaskId(taskId);
        HashMap<Integer,Boolean> subTaskIdMap=new HashMap<>();
        for(SubTaskAscription subTaskAscription :subTaskAscriptions){
            subTaskIdMap.put(subTaskAscription.getSubTaskId(),true);
        }*/
        int groupId=1;
        Integer maxGroupId=collaborationWorkMapper.selectMaxGroupId(taskId);
        while(groupId<=maxGroupId) {
            List<CollaborationWork> collaborationWorks = collaborationWorkMapper.selectAllByParentTaskIdAndGroupId(taskId, groupId);
            List<ReportSummaryVO> tempList=new ArrayList<>();
            for (CollaborationWork collaborationWork : collaborationWorks) {
                ReportSummaryVO temp=new ReportSummaryVO();
                temp.setTaskId(collaborationWork.getTaskId());
                temp.setWorkerId(collaborationWork.getUserId());
                Report report=reportMapper.selectByByTaskAndUser(collaborationWork.getUserId(),collaborationWork.getTaskId());
                if(report==null){
                    temp.setReportId(0);
                }else
                    temp.setReportId(report.getId());
                temp.setWorkerName(userMapper.selectByPrimaryKey(collaborationWork.getUserId()).getUsername());
                tempList.add(temp);
            }
            groupId++;
            res.add(tempList);
        }
        return new ResultVO<>(Constant.REQUEST_SUCCESS,"获取任务组成功", res);
    }

    @Override
    public ResultVO<List<Integer>> getCollaborationClaimedSubTask(Integer taskId) {
        List<SubTaskAscription> subTaskAscriptions=subTaskAscriptionMapper.selectByParentTaskId(taskId);
        if(subTaskAscriptions == null)
            return new ResultVO<>(Constant.REQUEST_FAIL,"获取所有子任务失败");
        List<Integer> res=new ArrayList<>();
        for(SubTaskAscription subTaskAscription :subTaskAscriptions){
            res.add(subTaskAscription.getSubTaskId());
        }
        return new ResultVO<>(Constant.REQUEST_SUCCESS,"获取所有子任务成功", res);
    }

    @Override
    public ResultVO<List<ReportSummaryVO>> getWorkerCollaborationTaskGroup(Integer taskId, Integer userId) {
        List<ReportSummaryVO> res=new ArrayList<>();
        CollaborationWork userCollaborationWork = collaborationWorkMapper.selectByParentTaskIdAndUserId(taskId, userId);
        if(userCollaborationWork==null||userCollaborationWork.getId()==null)
            return new ResultVO<>(Constant.REQUEST_FAIL,"该用户还未领取这个协作任务");
        List<CollaborationWork> collaborationWorks = collaborationWorkMapper.selectAllByParentTaskIdAndGroupId(userCollaborationWork.getParentTaskId(), userCollaborationWork.getGroupId());
        for (CollaborationWork collaborationWork : collaborationWorks) {
            ReportSummaryVO temp=new ReportSummaryVO();
            temp.setTaskId(collaborationWork.getTaskId());
            temp.setWorkerId(collaborationWork.getUserId());
            Report report=reportMapper.selectByByTaskAndUser(collaborationWork.getUserId(),collaborationWork.getTaskId());
            if(report==null){
                temp.setReportId(0);
            }else
                temp.setReportId(report.getId());
            temp.setWorkerName(userMapper.selectByPrimaryKey(collaborationWork.getUserId()).getUsername());
            res.add(temp);
        }
        return new ResultVO<>(Constant.REQUEST_SUCCESS,"获取用户所在任务组成功", res);
    }

    @Override
    public ResultVO<NullVO> pickSubTask(TaskClaimFormVO taskClaimFormVO) {
        Integer parentTaskId=subTaskAscriptionMapper.selectBySubTaskId(taskClaimFormVO.getSubTaskId()).getParentTaskId();
        Work work = new Work();
        work.setTaskId(parentTaskId);
        work.setUserId(taskClaimFormVO.getWorkerId());
        work.setStatus(1);
        int id = workMapper.insert(work);
        CollaborationWork collaborationWork=new CollaborationWork();
        collaborationWork.setIsCollocated(false);
        collaborationWork.setIsBeenCollocated(false);
        collaborationWork.setStatus(1);
        collaborationWork.setGroupId(0);
        collaborationWork.setParentTaskId(parentTaskId);
        collaborationWork.setUserId(taskClaimFormVO.getWorkerId());
        collaborationWork.setTaskId(taskClaimFormVO.getSubTaskId());
        int collaborationId=collaborationWorkMapper.insert(collaborationWork);
        collaborationWork.setId(collaborationWorkMapper.selectMaxId());
        List<CollaborationTaskDependency> upCollaborationTaskDependencies=collaborationTaskDependencyMapper.selectByDownstreamId(taskClaimFormVO.getSubTaskId());
        if(upCollaborationTaskDependencies!=null&&upCollaborationTaskDependencies.size()>0){
            for(CollaborationTaskDependency collaborationTaskDependencyTemp:upCollaborationTaskDependencies) {
                List<CollaborationWork> upWorkTemps = collaborationWorkMapper.selectByTaskAndNotBeenCollacatedCompleted(collaborationTaskDependencyTemp.getUpstreamId());
                if (upWorkTemps.size() > 0) {
                    CollaborationWork upTemp = upWorkTemps.get(0);
                    WorkCollocation recordWorkCollocation = new WorkCollocation();
                    recordWorkCollocation.setCollocatedWorkId(upTemp.getId());
                    recordWorkCollocation.setCollocatingWorkId(collaborationWork.getId());
                    workCollocationMapper.insert(recordWorkCollocation);
                    collaborationWork.setIsCollocated(true);
                    collaborationWork.setGroupId(upTemp.getGroupId());
                    upTemp.setIsBeenCollocated(true);
                    collaborationWorkMapper.updateByPrimaryKey(upTemp);
                    // 发送消息
                    WorkerMessage message = new WorkerMessage();
                    message.setCooReportId(0);
                    message.setMessageType(10);
                    message.setReportId(reportMapper.selectByByTaskAndUser(upTemp.getUserId(),upTemp.getTaskId()).getId());
                    message.setFromRole(1);
                    message.setSubmitTime(new Date());
                    message.setFromUserId(upTemp.getUserId());
                    message.setToWorkerId(collaborationWork.getUserId());
                    message.setStatus(0);
                    message.setTaskId(upTemp.getParentTaskId());
                    message.setTaskName(taskMapper.selectByPrimaryKey(upTemp.getParentTaskId()).getTaskName());
                    message.setMsgContent("协作任务：上游有任务已完成并将报告分配给您！");
                    int messageId = workerMessageMapper.insert(message);
                    WebSocketServer.sendMessageToSpecificUser(workerMessageMapper.countStatus(0, message.getToWorkerId()), message.getToWorkerId());
                }
            }
            collaborationWorkMapper.updateByPrimaryKey(collaborationWork);
        }else{
            int maxGroupId=collaborationWorkMapper.selectSubTaskMaxGroupId(taskClaimFormVO.getSubTaskId())+1;
            collaborationWork.setGroupId(maxGroupId+1);
            collaborationWork.setIsCollocated(true);
            collaborationWorkMapper.updateByPrimaryKey(collaborationWork);
            // 发送消息
            WorkerMessage message = new WorkerMessage();
            message.setCooReportId(0);
            message.setMessageType(10);
            message.setReportId(1);
            message.setFromRole(1);
            message.setSubmitTime(new Date());
            message.setFromUserId(4);
            message.setToWorkerId(collaborationWork.getUserId());
            message.setStatus(0);
            message.setTaskId(collaborationWork.getTaskId());
            message.setTaskName(taskMapper.selectByPrimaryKey(collaborationWork.getTaskId()).getTaskName());
            message.setMsgContent("协作任务：你没有上游任务，可以直接完成");
            int messageId = workerMessageMapper.insert(message);
            WebSocketServer.sendMessageToSpecificUser(workerMessageMapper.countStatus(0, message.getToWorkerId()), message.getToWorkerId());
        }
        if(id < 1||collaborationId<1)
            return new ResultVO<>(Constant.REQUEST_FAIL, "插入失败！");
        else{
            //该任务的need_num需要-1
            taskMapper.decreaseNeedNum(parentTaskId);
            taskMapper.decreaseNeedNum(taskClaimFormVO.getSubTaskId());
            return new ResultVO<>(Constant.REQUEST_SUCCESS, "插入成功",new NullVO());
        }
    }
}
